package com.jeff.snake.view;

import java.util.ArrayList;
import java.util.Random;

import com.jeff.snake.R;

import android.content.Context;
import android.content.res.Resources;
import android.graphics.Point;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.util.Log;

public class SnakeView extends TileView {

	private static final int RED_START = 1;
	private static final int GREEN_START = 2;
	private static final int OTHER_START = 3;

	private int mDirection = DOWN;
	private int mNextDirection = DOWN;
	private static final int UP = 1;
	private static final int DOWN = 2;
	private static final int LEFT = 3;
	private static final int RIGHT = 4;

	private int mMode = RUNNING;
	private static final int PAUSE = 1;
	private static final int READY = 2;
	private static final int RUNNING = 3;
	private static final int LOSE = 4;

	private long mScore = 0;
	private long mMoveDelay = 600;

	private ArrayList<Point> mSnakeList = new ArrayList<Point>();
	private ArrayList<Point> mAppleList = new ArrayList<Point>();

	private static final Random RANDOM = new Random();

	private RefreshHandler handler = new RefreshHandler();

	public SnakeView(Context context, AttributeSet attrs) {
		super(context, attrs);
		initSnakeView();
	}

	private void initSnakeView() {
		setColorTiles(4);
		Resources res = getResources();
		loadTile(RED_START, res.getDrawable(R.drawable.redstar));
		loadTile(GREEN_START, res.getDrawable(R.drawable.greenstar));
		loadTile(OTHER_START, res.getDrawable(R.drawable.otherstar));

		initNewGame();
	}

	private void initNewGame() {
		mScore = 0;
		mMoveDelay = 600;

		mSnakeList.add(new Point(5, 7));
		mSnakeList.add(new Point(4, 7));
		mSnakeList.add(new Point(3, 7));
		mSnakeList.add(new Point(2, 7));

		addRandomApple();
	}

	public void startGame() {
		update();
	}

	private void addRandomApple() {
		Point point = null;
		boolean found = false;

		while (!found) {
			int x = RANDOM.nextInt(X_TILE_COUNT);
			int y = RANDOM.nextInt(Y_TILE_COUNT);
			point = new Point(x, y);

			boolean collision = false;
			for (int i = 0, len = mSnakeList.size(); i < len; i++) {
				if (mSnakeList.get(i).equals(point)) {
					collision = true;
				}
			}
			found = !collision;
		}
		mAppleList.clear();
		mAppleList.add(point);
	}

	private void update() {
		clearGridTile();
		updateSnake();
		updateApple();
		handler.sleep();
	}

	private void updateSnake() {
		Point point = null;
		Point firstPoint = mSnakeList.get(0);
		switch (mNextDirection) {
		case UP:
			point = new Point(firstPoint.x, firstPoint.y - 1);
			break;
		case DOWN:
			point = new Point(firstPoint.x, firstPoint.y + 1);
			break;
		case LEFT:
			point = new Point(firstPoint.x - 1, firstPoint.y);
			break;
		case RIGHT:
			point = new Point(firstPoint.x + 1, firstPoint.y);
			break;
		}

		mSnakeList.add(0, point);
		mSnakeList.remove(mSnakeList.size() - 1);

		for (int i = 0, len = mSnakeList.size(); i < len; i++) {
			if (i == 0) {
				setGridTile(GREEN_START, mSnakeList.get(i).x, mSnakeList.get(i).y);
			} else {
				setGridTile(OTHER_START, mSnakeList.get(i).x, mSnakeList.get(i).y);
			}
		}
	}

	private void updateApple() {
		setGridTile(RED_START, mAppleList.get(0).x, mAppleList.get(0).y);
	}

	class RefreshHandler extends Handler {

		public void handleMessage(Message msg) {
			update();
			invalidate();
			Log.d("@@@", "handleMessage");
			super.handleMessage(msg);
		}

		public void sleep() {
			Message msg = obtainMessage();
			handler.sendMessageDelayed(msg, mMoveDelay);
		}
	}
}
